package com.wang.springbootinit.service.impl;


import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wang.springbootinit.common.ErrorCode;
import com.wang.springbootinit.exception.BusinessException;
import com.wang.springbootinit.mapper.ExcelInfoMapper;
import com.wang.springbootinit.model.entity.Chart;
import com.wang.springbootinit.model.entity.ExcelInfo;
import com.wang.springbootinit.model.entity.User;
import com.wang.springbootinit.model.enums.ChartStatusEnum;
import com.wang.springbootinit.model.param.BaseExcelInfoUpdate;
import com.wang.springbootinit.model.param.ExcelInfoUpdateParam;
import com.wang.springbootinit.model.vo.ExcelInfoVO;
import com.wang.springbootinit.service.ChartService;
import com.wang.springbootinit.service.ExcelInfoService;
import com.wang.springbootinit.service.UserService;
import com.wang.springbootinit.utils.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 胡歌的腿毛
 * @description 针对表【excel_info(excel数据信息表)】的数据库操作Service实现
 * @createDate 2023-09-07 22:11:49
 */
@Service
@Slf4j
public class ExcelInfoServiceImpl extends ServiceImpl<ExcelInfoMapper, ExcelInfo>
        implements ExcelInfoService {
    @Resource
    private UserService userService;

    @Resource
    private ChartService chartService;


    /**
     * 获取excelInfo 数据信息
     *
     * @param chartId excel表id
     * @param request
     * @return
     */
    @Override
    public ExcelInfoVO getExcelInfo(Long chartId, HttpServletRequest request) {
        if (chartId < 0) {
            log.info("getExcelInfo 获取excel表格信息 参数chartId错误 {}", chartId);
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            log.info("getExcelInfo 用户未登录");
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, ErrorCode.NOT_LOGIN_ERROR.getMessage());
        }
        Chart chart = chartService.getById(chartId);
        if (!chart.getStatus().equals(ChartStatusEnum.SUCCEED)) {
            log.info("getExcelInfo 图表还未生产或者图表生产失败情况");
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, ErrorCode.SYSTEM_ERROR.getMessage());
        }

        return this.getExcelListData(chartId);

    }

    @Override
    public Boolean updateExcelInfo(ExcelInfoUpdateParam excelInfoUpdateParam) {
        Long chartId = excelInfoUpdateParam.getChartId();

        //获取原本数据
        ExcelInfoVO excelListData = this.getExcelListData(chartId);
        List<Map<Integer, String>> excelData = excelListData.getExcelData();

        //更新list数据
        List<BaseExcelInfoUpdate> excelInfoUpdateList = excelInfoUpdateParam.getExcelInfoUpdateList();
        log.info("updateExcelInfo 要更新的数据: {}", JSONUtil.toJsonStr(excelInfoUpdateList));
        for (int i = 0; i < excelData.size(); i++) {
            if (excelInfoUpdateList.get(i).getRow() == i) {
                Map<Integer, String> integerStringMap = excelData.get(i);
                integerStringMap.put(excelInfoUpdateList.get(i).getCol(), excelInfoUpdateList.get(i).getUpdateValue());
                excelData.set(i, integerStringMap);
            }
        }

        //更新数据库
        String excelInfoStr = ExcelUtils.ExcelDataToJson(excelData);
        ExcelInfo excelInfo = new ExcelInfo();
        excelInfo.setChartId(chartId);
        excelInfo.setExcelData(excelInfoStr);
        QueryWrapper<ExcelInfo> excelInfoQueryWrapper = new QueryWrapper<>();
        excelInfoQueryWrapper.eq("chartId", chartId);
        boolean result = this.update(excelInfo, excelInfoQueryWrapper);
        if (!result) {
            log.info("ExcelInfoServiceImpl updateExcelInfo 保存数据库错误");
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "保存数据错误");
        }
        return result;
    }

    /**
     * 通用方法  从数据获取excel数据并转为list的vo数据
     *
     * @param chartId
     * @return
     */
    public ExcelInfoVO getExcelListData(Long chartId) {
        QueryWrapper<ExcelInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("chartId", chartId);

        List<ExcelInfo> excelInfoList = this.list(queryWrapper);
        //多条数据情况
        /**
         * 这里给的一条数据最大10万条，一般走不到多条数据的情况
         */
        if (excelInfoList.size() > 1) {
            log.error("getExcelInfo 数据量过大，分段存储，需要拼接成一个list");
            log.error("警告!! getExcelInfo 数据量过大，多次获取数据的情况会出现大量冗余数据，警告！！");
            List<Map<Integer, String>> excelInfoManyList = new ArrayList<>();
            //List<Map<Integer, String>> mapList = ExcelUtils.JsonToExcelData(excelInfoList.get(0).getExcel_data());
            for (ExcelInfo excelInfo : excelInfoList) {
                List<Map<Integer, String>> maps = ExcelUtils.JsonToExcelData(excelInfo.getExcelData());
                excelInfoManyList.addAll(maps);
            }
            ExcelInfoVO excelInfoVO = new ExcelInfoVO();
            excelInfoVO.setChartId(chartId);
            excelInfoVO.setExcelData(excelInfoManyList);
            return excelInfoVO;
        }

        //单条数据情况
        log.info("getExcelInfo 单条数据情况");
        ExcelInfo excelInfo = excelInfoList.get(0);
        ExcelInfoVO excelInfoVO = new ExcelInfoVO();
        excelInfoVO.setChartId(excelInfo.getChartId());
        List<Map<Integer, String>> excelList = ExcelUtils.JsonToExcelData(excelInfo.getExcelData());
        excelInfoVO.setExcelData(excelList);
        return excelInfoVO;
    }
}




